package com.luoye.lj.util.converter;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: Dave Liu
 * Date: 2015/12/20
 * Time: 19:49
 * To change this template use File | Settings | File Templates.
 */
public class ObjStrMapConverter {
    private Map<String, String> strMap;
    private Object object;

    public ObjStrMapConverter() {
    }

    public ObjStrMapConverter(Map<String, String> strMap, Object object) {
        this.strMap = strMap;
        this.object = object;
    }

    public Map<String, String> getStrMap() {
        return strMap;
    }

    public void setStrMap(Map<String, String> strMap) {
        this.strMap = strMap;
    }

    public Object getObject() {
        return object;
    }

    public void setObject(Object object) {
        this.object = object;
    }

    //对象转换为MAP
    public void convertToMap() {
        convertToMap("",strMap,object);
    }
    private void convertToMap(String prefix, Map<String, String> strMap, Object object){
        if(strMap==null||prefix==null){
            return;
        }
        if(object==null&&!"".equals(prefix)){
            if(prefix.indexOf("-")>-1){
                prefix=prefix.substring(0,prefix.indexOf("-"));
            }
            strMap.put(prefix,"null");
            return;
        }
        Field[] sFields = object.getClass().getDeclaredFields();
        for (Field sField : sFields) {
            String sFieldName = sField.getName();
            Class sFieldType=sField.getType();
            String sFieldTypeName=sField.getType().getSimpleName();
            sField.setAccessible(true);
            try {
                if(sField.get(object)==null){
                    strMap.put(prefix + sFieldName, "null");
                    continue;
                }
                if(sFieldType.isPrimitive()){//基本数据类型
                    strMap.put(prefix+sFieldName,sField.get(object) + "");
                }else {
                    if ("Date".equals(sFieldTypeName)) {
                        SimpleDateFormat sdtf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        String dateStr = sdtf.format(sField.get(object));
                        strMap.put(prefix+sFieldName, dateStr);
                    } else if("String".equals(sFieldTypeName)) {
                        strMap.put(prefix+sFieldName, sField.get(object) + "");
                    } else if(List.class.isAssignableFrom(sFieldType)) {//list
                        List list= (List) sField.get(object);
                        if(list==null){
                            strMap.put(prefix+sFieldName,"null");
                        }else{
                            int i=0;
                            for(Object obj:list){
                                if(obj==null){
                                    strMap.put(prefix+sFieldName + "[" + i + "]","null");
                                }else if(obj instanceof String){
                                    strMap.put(prefix+sFieldName + "[" + i + "]",obj.toString());
                                }else if(obj instanceof Date){
                                    SimpleDateFormat sdtf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                    String dateStr = sdtf.format(obj);
                                    strMap.put(prefix+sFieldName + "[" + i + "]", dateStr);
                                }else if(obj instanceof Integer){
                                    strMap.put(prefix+sFieldName + "[" + i + "]",obj.toString());
                                }else if(obj instanceof Float){
                                    strMap.put(prefix+sFieldName + "[" + i + "]",obj.toString());
                                }else if(obj instanceof Double){
                                    strMap.put(prefix+sFieldName + "[" + i + "]",obj.toString());
                                }else if(obj instanceof Boolean){
                                    strMap.put(prefix+sFieldName + "[" + i + "]",obj.toString());
                                }else if(obj instanceof Byte){
                                    strMap.put(prefix+sFieldName + "[" + i + "]",obj.toString());
                                }else if(obj instanceof Character){
                                    strMap.put(prefix+sFieldName + "[" + i + "]",obj.toString());
                                }else if(obj instanceof Short){
                                    strMap.put(prefix+sFieldName + "[" + i + "]",obj.toString());
                                }else if(obj instanceof Long){
                                    strMap.put(prefix+sFieldName + "[" + i + "]",obj.toString());
                                }else {
                                    strMap.put(prefix + sFieldName + "[" + i + "]", obj.toString());
                                    convertToMap(prefix + sFieldName + "[" + i + "]-", strMap, obj);
                                }
                                i++;
                            }
                            strMap.put(prefix+sFieldName,i+"");
                        }
                    }else{
                        if(sField.get(object)!=null) {
                            strMap.put(prefix + sFieldName, sField.get(object).toString());
                            convertToMap(prefix + sFieldName + "-", strMap, sField.get(object));
                        }else {
                            strMap.put(prefix + sFieldName, "null");
                        }
                    }
                }
            }catch (IllegalAccessException ex) {
                //ex.printStackTrace();
            }
        }
    }

    private void convertToObject(String prefix, Map<String, String> strMap, Object object){
        if(strMap==null||prefix==null||object==null){
            return;
        }
        Field[] sFields = object.getClass().getDeclaredFields();
        for (Field sField : sFields) {
            String sFieldName = sField.getName();
            Class sFieldType=sField.getType();
            String sFieldTypeName=sField.getType().getSimpleName();
            sField.setAccessible(true);
            try {
                String mapValue=strMap.get(prefix+sFieldName);
                if(mapValue==null||"null".equals(mapValue)){
                    sField.set(object, null);
                    continue;
                }
                if(sFieldType.isPrimitive()){//基本数据类型
                    if ("int".equals(sFieldTypeName)) {
                        try {
                            int value= Integer.parseInt(mapValue);
                            sField.set(object,value);
                        }catch (NumberFormatException ex){
                            ex.printStackTrace();;
                        }
                    } else if ("long".equals(sFieldTypeName)) {
                        try {
                            long value= Long.parseLong(mapValue);
                            sField.set(object,value);
                        }catch (NumberFormatException ex){
                            ex.printStackTrace();;
                        }
                    } else if ("float".equals(sFieldTypeName)) {
                        try {
                            float value= Float.parseFloat(mapValue);
                            sField.set(object,value);
                        }catch (NumberFormatException ex){
                            ex.printStackTrace();;
                        }
                    } else if ("double".equals(sFieldTypeName)) {
                        try {
                            double value= Double.parseDouble(mapValue);
                            sField.set(object,value);
                        }catch (NumberFormatException ex){
                            ex.printStackTrace();;
                        }
                    } else if ("char".equals(sFieldTypeName)) {
                        try {
                            char value=(char) Integer.parseInt(mapValue);
                            sField.set(object,value);
                        }catch (NumberFormatException ex){
                            ex.printStackTrace();;
                        }
                    } else if ("byte".equals(sFieldTypeName)) {
                        try {
                            byte value= Byte.parseByte(mapValue);
                            sField.set(object,value);
                        }catch (NumberFormatException ex){
                            ex.printStackTrace();;
                        }
                    } else if ("short".equals(sFieldTypeName)) {
                        try {
                            short value= Short.parseShort(mapValue);
                            sField.set(object,value);
                        }catch (NumberFormatException ex){
                            ex.printStackTrace();;
                        }
                    }
                    else if ("boolean".equals(sFieldTypeName)) {
                        try {
                            boolean value= Boolean.parseBoolean(mapValue);
                            sField.set(object,value);
                        }catch (NumberFormatException ex){
                            ex.printStackTrace();;
                        }
                    }
                }else {
                    if ("Date".equals(sFieldTypeName)) {
                        SimpleDateFormat sdtf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        try {
                            Date value=sdtf.parse(mapValue);
                            sField.set(object,value);
                        }catch (ParseException ex){
                            ex.printStackTrace();;
                        }
                    }else if ("String".equals(sFieldTypeName)) {
                        String value=mapValue;
                        sField.set(object,value);
                    }else if(List.class.isAssignableFrom(sFieldType)) {//list
                        int size=0;
                        try {
                            size= Integer.parseInt(mapValue);
                        }catch (NumberFormatException ex){
                            //ex.printStackTrace();;
                        }
                        List list=new ArrayList();
                        try {
                           list= (List) sFieldType.newInstance();
                        } catch (InstantiationException e) {
                            //e.printStackTrace();
                        }
                        Type gt = sField.getGenericType();   //得到泛型类型
                        ParameterizedType pt = (ParameterizedType)gt;
                        Class tClass = (Class)pt.getActualTypeArguments()[0];
                        String tClassName=tClass.getSimpleName();
                        //System.out.println("tClassName->"+tClassName);
                        for (int i=0;i<size;i++){
                            Object objInstance=null;//tClass.newInstance();
                            mapValue=strMap.get(prefix + sFieldName + "[" + i + "]");
                            if(mapValue==null||"null".equals(mapValue)){
                                objInstance=null;
                            }else if ("Integer".equals(tClassName)) {//基本数据类型
                                try {
                                    objInstance= Integer.parseInt(mapValue);
                                }catch (NumberFormatException ex){
                                    ex.printStackTrace();;
                                }
                            } else if ("Long".equals(tClassName)) {
                                try {
                                    objInstance= Long.parseLong(mapValue);
                                }catch (NumberFormatException ex){
                                    ex.printStackTrace();;
                                }
                            } else if ("Float".equals(tClassName)) {
                                try {
                                    objInstance= Float.parseFloat(mapValue);
                                }catch (NumberFormatException ex){
                                    ex.printStackTrace();;
                                }
                            } else if ("Double".equals(tClassName)) {
                                try {
                                    objInstance= Double.parseDouble(mapValue);
                                }catch (NumberFormatException ex){
                                    ex.printStackTrace();;
                                }
                            } else if ("Character".equals(tClassName)) {
                                try {
                                    objInstance=(char) Integer.parseInt(mapValue);
                                }catch (NumberFormatException ex){
                                    ex.printStackTrace();;
                                }
                            } else if ("Byte".equals(tClassName)) {
                                try {
                                    objInstance= Byte.parseByte(mapValue);
                                }catch (NumberFormatException ex){
                                    ex.printStackTrace();;
                                }
                            } else if ("Short".equals(tClassName)) {
                                try {
                                    objInstance= Short.parseShort(mapValue);
                                }catch (NumberFormatException ex){
                                    ex.printStackTrace();;
                                }
                            }
                            else if ("Boolean".equals(tClassName)) {
                                try {
                                    objInstance= Boolean.parseBoolean(mapValue);
                                }catch (NumberFormatException ex){
                                    ex.printStackTrace();;
                                }
                            }else if ("Date".equals(tClassName)) {
                                SimpleDateFormat sdtf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                try {
                                    objInstance= sdtf.parse(mapValue);
                                } catch (ParseException ex) {
                                    ex.printStackTrace();
                                    ;
                                }
                            } else if ("String".equals(tClassName)) {
                                objInstance= mapValue;
                            }else {
                                try {
                                    objInstance = tClass.newInstance();
                                } catch (InstantiationException e) {
                                    e.printStackTrace();
                                }
                                //System.out.println("objInstance->"+objInstance);
                                convertToObject(prefix + sFieldName + "[" + i + "]-", strMap, objInstance);
                            }
                            list.add(objInstance);
                        }
                        sField.set(object,list);
                    }else{
                        if(mapValue!=null&&!"null".equals(mapValue)) {
                            Object objInstance = null;
                            try {
                                objInstance = sFieldType.newInstance();
                            } catch (InstantiationException e) {
                                e.printStackTrace();
                            }
                            convertToObject(prefix + sFieldName + "-", strMap, objInstance);
                            sField.set(object, objInstance);
                        }
                    }
                }
            }catch (IllegalAccessException ex) {
                //ex.printStackTrace();
            }
        }
    }
    //map转换为对象
    public void convertToObject() {
        convertToObject("",strMap,object);
    }
}
